﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Agile.Engine.Data
{
    public class DataContext
    {

        private DataContext() { }

        public DataContext(string dbProviderAlias)
        {
            DataProvider = ObjectContext.GetDbProvider(dbProviderAlias);
        }

        /// <summary>
        /// 数据来源
        /// </summary>
        public Spring.Data.Common.IDbProvider DataProvider
        {
            get { return dataProvider; }
            set
            {
                dataProvider = value;
                DataTemplate = new Spring.Data.Core.AdoTemplate(value);
                model = new DataModel() { DataContext = this };
            }
        }

        public string DbProvider { get { return DataProvider.DbMetadata.ProductName; } }
        private Spring.Data.Common.IDbProvider dataProvider;
        private DataModel model;

        /// <summary>
        /// Ado 数据访问模板
        /// </summary>
        public Spring.Data.Core.AdoTemplate DataTemplate { get; set; }

        /// <summary>
        /// 手工创建
        /// </summary>
        /// <param name="provider"></param>
        /// <param name="connstr"></param>
        /// <returns></returns>
        public static DataContext Create(string provider, string connstr)
        {
            var p = Spring.Data.Common.DbProviderFactory.GetDbProvider(provider);
            p.ConnectionString = connstr;
            DataContext c = new DataContext() { DataProvider = p };
            return c;
        }

        public static DataContext ExcelContext(string path)
        {
            var p = "System.Data.OleDb";
            var str = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source='{0}';Extended Properties='Excel 8.0;IMEX=1';";
            return Create(p, string.Format(str, path));
        }

        public static DataContext AccessContext(string path)
        {
            var p = "System.Data.OleDb";
            var str = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source='{0}';";
            return Create(p, string.Format(str, path));
        }

        public static DataContext SqlceContext(string path)
        {
            var p = "System.Data.SqlServerCe";
            var str = "Data Source={0}";
            return Create(p, string.Format(str, path));
        }

        /// <summary>
        /// 配置获取
        /// </summary>
        /// <param name="alias"></param>
        /// <returns></returns>
        public static DataContext Get(string alias)
        {
            return ObjectContext.DefaultContext.GetObject(alias) as DataContext;
        }

        /// <summary>
        /// 重设连接字符串
        /// </summary>
        /// <param name="connstr"></param>
        public void ResetConnString(string connstr)
        {
            DataProvider.ConnectionString = connstr;
        }

        public void ResetConnString(System.Collections.Hashtable model)
        {
            var connstr = DataProvider.ConnectionString;
            var newstr = Utils.VelocityUtils.MergeString(connstr, model);
            ResetConnString(newstr);
        }

        public string GetConnString
        {
            get { return DataProvider.ConnectionString; }
        }

        /// <summary>
        /// 数据访问模型
        /// </summary>
        /// <returns></returns>
        public DataModel DefaultModel
        {
            get { return model; }
        }

        /// <summary>
        /// 手工创建数据逻辑处理
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public T CreateRule<T>(System.Collections.Hashtable param)
            where T : DataRule, new()
        {
            return new T() { Model = DefaultModel, Paramater = param };
        }

        /// <summary>
        /// 执行数据逻辑并返回实例
        /// </summary>
        /// <param name="alias"></param>
        /// <param name="param"></param>
        /// <returns></returns>
        public DataRule ExecuteRule(string alias, System.Collections.Hashtable param)
        {
            var rule = (ObjectContext.GetObject(alias) as DataRule);
            rule.Model = DefaultModel;
            rule.ExecuteTrans(param);
            return rule;
        }
    }
}
